package com.cyh.core.framework.mapper;

/**
 * @Author: yanhang_chen
 * @Date: 2020/9/14 9:28
 */
import com.cyh.core.framework.common.model.TreeNode;
import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 把零散的TreeNode对象的数据集合转换成规范的树形结构
 * TreeNodeMapper.coverToTree(nodes);
 */
public class TreeNodeMapper {

    /**
     * 根据TreeNode列表来构建树（支持多棵树）
     *
     * @param nodes 菜单列表
     * @return 构建后的树（森林）
     */
    public static <T extends TreeNode> Collection<T> coverToTree(Collection<T> nodes) {
        return getTree(new LinkedList<>(nodes));
    }

    private static <T extends TreeNode> Collection<T> getTree(Collection<T> nodes) {

        if (CollectionUtils.isEmpty(nodes)) {
            return Collections.emptyList();
        }

        //找出所有根节点
        //List<T> rootNodes = new LinkedList<>();
        List<T> rootNodes = nodes.stream().filter(node -> StringUtils.isEmpty(node.getParentNodeId()))
                .collect(Collectors.toList());
        /*for (T node : nodes) {
            if (StringUtils.isEmpty(node.getParentNodeId())) {
                rootNodes.add(node);
            }
        }*/

        //已找到的就去掉，减少遍历数据量
        nodes.removeAll(rootNodes);

        //构建树
        buildTree(rootNodes, nodes);

        return rootNodes;
    }

    /**
     * 递归创建树集合
     *
     * @param rootNodes 根节点集合
     * @param nodes 子节点集合
     * @return 创建后的树集合
     */
    @SuppressWarnings("unchecked")
    private static <T extends TreeNode> boolean buildTree(Collection<T> rootNodes, Collection<T> nodes) {
        List<T> childNodes = Lists.newCopyOnWriteArrayList(nodes);
        // 从集合中 挑选出父集合rootNodes对应的子节点
        /*for (T rootNode : rootNodes) {
            for (T m : childNodes) {
                if (!StringUtils.isEmpty(m.getParentNodeId())
                        && m.getParentNodeId().equals(rootNode.getCurrentNodeId())) {
                    // 为父节点添加子节点
                    rootNode.addChildNode(m);
                    // 从节点集合中删除掉已经找到父节点的节点，减少迭代次数
                    nodes.remove(m);
                }
            }
        }*/
        // 从集合中 挑选出父集合rootNodes对应的子节点
        rootNodes.forEach(rootNode ->
                childNodes.stream().filter(child -> isChild(rootNode, child)).forEach(child -> {
                    rootNode.addChildNode(child);
                    nodes.remove(child);
                })
        );

        if (nodes.isEmpty()) {   //没有备选节点了
            return false;
        }


        for (T rootNode : rootNodes) {
            // 判断父节点是否存在子节点，如果存在，继续为子节点寻找孙节点，递归遍历下去
            if (!CollectionUtils.isEmpty(rootNode.getChildNodes()))
                if (!buildTree(rootNode.getChildNodes(), nodes) ){
                    return false;
                }
        }

        return true;
    }

    private static <T extends TreeNode> boolean isChild(T rootNode, T node) {
        return !StringUtils.isEmpty(node.getParentNodeId()) && node.getParentNodeId().equals(rootNode.getCurrentNodeId());
    }

}

